package org.lmind.example.util.common;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 占位符解析器
 * @author mian.liu
 *
 */
public class PlaceholderResolver {
	
	/** 默认的占位符前缀 */
	public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

	/** 默认的占位符后缀 */
	public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
	
	/** 实际使用的占位符前缀 */
	private String placeholderPrefix = DEFAULT_PLACEHOLDER_PREFIX;
	
	/** 实际使用的占位符后缀 */
	private String placeholderSuffix = DEFAULT_PLACEHOLDER_SUFFIX;
	
	/** 占位符解析时使用的正则表达式 */
	private Pattern pattern;
	
	public PlaceholderResolver() {
		pattern = Pattern.compile(Pattern.quote(placeholderPrefix) + "(.*?)" + Pattern.quote(placeholderSuffix));
	}

	/**
	 * @param placeholderPrefix
	 * @param placeholderSuffix
	 */
	public PlaceholderResolver(String placeholderPrefix, String placeholderSuffix) {
		this.placeholderPrefix = placeholderPrefix;
		this.placeholderSuffix = placeholderSuffix;
		pattern = Pattern.compile(Pattern.quote(placeholderPrefix) + "(.*?)" + Pattern.quote(placeholderSuffix));
	}
	
	public Resolver resolver(String text) {
		return new Resolver(text);
	}
	
	
	
	public class Resolver implements Enumeration<Placeholder> {
		
		private String text;
		
		private Matcher matcher;
		
		private Placeholder next;

		/** 解析和替换结果 */
		private ArrayList<Placeholder> resolvedItems = new ArrayList<Placeholder>();
		
		public Resolver(String text) {
			super();
			this.text = text;
			matcher = pattern.matcher(text);
			nextElement();
		}

		@Override
		public boolean hasMoreElements() {
			return next != null;
		}

		@Override
		public Placeholder nextElement() {
			Placeholder old = next;
			if (matcher.find()) {
				next = new Placeholder(matcher.start(), matcher.end(), matcher.group(1));
				next.replacement = matcher.group();
				resolvedItems.add(next);
			} else {
				next = null;
			}
			return old;
		}
		
		public String build() {
			StringBuilder sb = new StringBuilder();
			
			int offset = 0;
			for (Placeholder item : resolvedItems) {
				sb.append(text.substring(offset, item.start));
				sb.append(item.replacement);
				offset = item.end;
			}
			sb.append(text.substring(offset));
			return sb.toString();
		}
	}
	
	
	public class Placeholder {
		
		private int start;
		
		private int end;
		
		private String key;
		
		private String replacement = "";
		
		/**
		 * @param start
		 * @param end
		 * @param key
		 */
		public Placeholder(int start, int end, String key) {
			super();
			this.start = start;
			this.end = end;
			this.key = key;
		}

		public String getKey() {
			return key;
		}

		public void replace(String replacement) {
			if (replacement == null)
				throw new IllegalArgumentException();
			this.replacement = replacement;
		}
	}
}
